home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Mac Format 1997 July
/
macformat52.iso
/
mac
/
Shareware Plus
/
Educational
/
LEE 2.1
/
Source
/
main.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-08-07
|
13KB
|
628 lines
/* lee.c
* Copyright (1992)
*
* Jeff Elman. University of California, San Diego
* Rik Belew. University of California, San Diego
* Stefano Nolfi. Institute of Psychology, Rome.
* Filippo Menczer. University of California, San Diego
* Greg Linden. University of California, San Diego
*
* This software may be redistributed without charge;
* this notice should be preserved.
*/
#include "defs.h"
/*
* generate a file name using a root and a suffix
*/
genfilen(filename,root,suffix)
char *filename;
char *root;
char *suffix;
{
sprintf(filename,"%s.%s",root,suffix);
}
main(argc, argv)
int argc;
char **argv;
{
int n_weights=0;
int n_biases=0;
boolean w_mu_flag=0;
boolean b_mu_flag=0;
float p_w_mu;
float p_b_mu;
int i;
int c;
InteractiveInit(&argc, &argv);
seed = (unsigned long)time(NULL);
carica_sigmoide();
for (i=0;i<4;i++)
for (c=0;c<MAXRANGESIZE;c++)
off_vec[i][c] = (offset *)malloc(sizeof(offset));
carica_offsets(MAXRANGE);
/*
* we read the command-line options
*/
while ((c = getopt(argc, argv, "R:E:L:Sf:s:p:r:G:P:g:h:n:o:bUv:d:e:u")) != EOF) {
switch (c) {
case 'R':
seed = (unsigned long)atol(optarg);
break;
case 'E':
ecount = atoi(optarg);
errsig=TRUE;
break;
case 'L':
learn = atoi(optarg);
if ((learn != 1) && (learn != 2))
{
printf("\nError in learning (-L) option\n\n");
usage();
exit(2);
}
break;
case 'S':
saturation=TRUE;
break;
case 'f':
strcpy(fileroot, optarg);
break;
case 's':
sweeps = atoi(optarg);
break;
case 'p':
if ( *optarg== 'o')
printout=TRUE;
break;
case 'r':
rate = (float) atof(optarg);
break;
case 'G':
generations = atoi(optarg);
break;
case 'P':
start_num_amoebas = atoi(optarg);
break;
case 'g':
startgeneration = atoi(optarg);
break;
case 'h':
mutations_range = atof(optarg);
break;
case 'n':
w_mu_flag++;
p_w_mu = (float)atoi(optarg)/100.0;
break;
case 'o':
b_mu_flag++;
p_b_mu = (float)atoi(optarg)/100.0;
break;
case 'b':
mbiasestoo=FALSE;
break;
case 'U':
unary_reactions=TRUE;
break;
case 'v':
verbose = atoi(optarg);
break;
case 'd':
save_best = atoi(optarg);
break;
case 'e':
save_everyn = atoi(optarg);
break;
case 'u':
case '?':
default:
usage();
exit(2);
break;
}
}
if (errsig && (learn !=2))
{
printf("\nWarning: cannot record prediction error in absence\n");
printf(" of prediction learning\n");
errsig = FALSE;
ecount = 0;
}
/*
* we configure the network and figure out mutations;
*/
config();
for (i=1;i<nlayers;i++)
{
n_weights += (*(layer_descp+i-1) * *(layer_descp+i));
n_biases += *(layer_descp + i);
}
if (w_mu_flag) mutations = (int)(p_w_mu * n_weights);
else mutations = (int)(WMUPE * n_weights);
if (b_mu_flag) bmutations = (int)(p_b_mu * n_biases);
else bmutations = (int)(BMUPE * n_biases);
/*
* print command information on the screen
*/
if (verbose > 0) {
printf("\n\n");
printf("Configuration file : %s\n", fileroot);
printf("Stop at generation : %d\n",generations);
printf("Life sweeps per generation : %d\n", sweeps);
printf("Neural net's architecture : ");
for (i=0; i < (nlayers -1); i++)
printf("%d -> ", *(layer_descp + i));
printf("%d\n", *(layer_descp + i));
printf("Gutsize : %d\n",gutsize);
if (learn)
printf("Learning rate : %.2f\n",rate);
if (startgeneration > 0)
printf("We start at generation : %d\n",startgeneration);
else
{
printf("Random seed : %lu\n", seed);
printf("Initial population : %d\n",start_num_amoebas);
}
printf("Number of weight mutations : %d\n",mutations);
if (mbiasestoo)
printf("Number of bias mutations : %d\n",bmutations);
printf("Range of mutations : %.2f\n",mutations_range);
if (save_best > 0)
printf("Saving only the %d best each generation\n",save_best);
if (save_everyn > 0)
printf("Saving individuals each %d generations\n",save_everyn);
if (errsig && (learn == 2))
printf("Saving global prediction error each %d sweeps\n", ecount);
printf("\n\n");
}
/*
* load or initialize state, world,
* and population (order is important!)
*/
if (startgeneration > 0)
{
load_all_indiv(startgeneration);
load_world(startgeneration);
}
else
{
Srand((long)seed);
init_world();
pop_size = start_num_amoebas;
init_pop(pop_size);
}
InteractiveFinalSetUp();
/*
* main generational loop
*/
generati();
}
/*
* Read simulation parameters from file "lee-config"
* (or other name determined by -f option).
* Comments begin with '#' and are skipped.
* Lines should be less than 256 characters long.
* Order matters!!!!
*/
config()
{
FILE *cfp;
char line[256];
char c;
register int i;
register int x,y,z;
int *ldp;
int n, m;
cfp = fopen(fileroot, "r");
if (cfp == NULL)
{
printf("ERROR: file %s not found", fileroot);
exit(1);
}
/*
* read size of world
*/
c = getc(cfp);
while (c == '#')
{
fgets(line,256,cfp);
c = getc(cfp);
}
ungetc(c,cfp);
m=fscanf(cfp,"%d ",&x_dim);
if (m!=1)
{
printf("ERROR: Reading from configuration file.\n");
exit(1);
}
c = getc(cfp);
while (c == '#')
{
fgets(line,256,cfp);
c = getc(cfp);
}
ungetc(c,cfp);
m=fscanf(cfp,"%d ",&y_dim);
if (m!=1)
{
printf("ERROR: Reading from configuration file.\n");
exit(1);
}
if ((x_dim > MAX_X) || (y_dim > MAX_Y))
{
printf("ERROR: World x or y dimension too large.\n");
printf(" Either decrease size from configuration file, or\n");
printf(" increase limits (file defs.h) and recompile code.\n");
exit(1);
}
/*
* read atom types and distributions
*/
c = getc(cfp);
while (c == '#')
{
fgets(line,256,cfp);
c = getc(cfp);
}
ungetc(c,cfp);
m=fscanf(cfp,"%d ",&types);
if (m!=1)
{
printf("ERROR: Reading from configuration file.\n");
exit(1);
}
if (types > MAXTYPES)
{
printf("ERROR: Number of types too large.\n");
printf(" Either decrease types from configuration file, or\n");
printf(" increase limit (file defs.h) and recompile code.\n");
exit(1);
}
c = getc(cfp);
while (c == '#')
{
fgets(line,256,cfp);
c = getc(cfp);
}
ungetc(c,cfp);
for (i=0; i<types; i++)
{
m=fscanf(cfp,"(%d,%d,%d,%d,%d) ",
&distrib[i][0], &distrib[i][1], &distrib[i][2],
&distrib[i][3], &distrib[i][4]);
if (m!=5)
{
printf("ERROR: Reading from configuration file.\n");
exit(1);
}
if ((distrib[i][0]<0) || (distrib[i][0]>=x_dim) ||
(distrib[i][1]<0) || (distrib[i][1]>=y_dim) ||
(distrib[i][2]<1) || (distrib[i][2]>6) ||
(distrib[i][3]<1) || (distrib[i][3]>6) ||
(distrib[i][4]<0) || (distrib[i][4]>100))
{
printf("ERROR: Incorrect distribution parameters.\n");
printf(" Please follow directions in configuration\n");
printf(" file and adjust parameters accordingly.\n");
exit(1);
}
}
/*
* next the numbers and types of sensors and motors
*/
c = getc(cfp);
while (c == '#')
{
fgets(line,256,cfp);
c = getc(cfp);
}
ungetc(c,cfp);
m=fscanf(cfp,"%d ",&nsensors);
if (m!=1)
{
printf("ERROR: Reading from configuration file.\n");
exit(1);
}
if (nsensors > MAXSENSORS)
{
printf("ERROR: Number of sensors too large.\n");
printf(" Either decrease sensors from configuration file, or\n");
printf(" increase limit (file defs.h) and recompile code.\n");
exit(1);
}
c = getc(cfp);
while (c == '#')
{
fgets(line,256,cfp);
c = getc(cfp);
}
ungetc(c,cfp);
for (i=0; i<nsensors; i++)
{
m=fscanf(cfp,"(%d,%d,%d) ", &s_type[i], &s_orient[i], &s_range[i]);
if (m!=3)
{
printf("ERROR: Reading from configuration file.\n");
exit(1);
}
if ((s_orient[i]<-1) || (s_orient[i]>2) ||
(s_range[i]<1) || (s_range[i]>MAXRANGE))
{
printf("ERROR: Incorrect sensor specifications.\n");
printf(" Please follow directions in configuration\n");
printf(" file and adjust parameters accordingly.\n");
exit(1);
}
}
c = getc(cfp);
while (c == '#')
{
fgets(line,256,cfp);
c = getc(cfp);
}
ungetc(c,cfp);
m=fscanf(cfp,"%d ",&nmotors);
if (m!=1)
{
printf("ERROR: Reading from configuration file.\n");
exit(1);
}
if (nmotors > MAXMOTORS)
{
printf("ERROR: Number of motors too large.\n");
printf(" Either decrease motors from configuration file, or\n");
printf(" increase limit (file defs.h) and recompile code.\n");
exit(1);
}
c = getc(cfp);
while (c == '#')
{
fgets(line,256,cfp);
c = getc(cfp);
}
ungetc(c,cfp);
for (i=0; i<nmotors; i++)
{
m=fscanf(cfp, "%d ", &m_type[i]);
if (m!=1)
{
printf("ERROR: Reading from configuration file.\n");
exit(1);
}
}
/*
* read # of hidden layers and add 2 for input and output
*/
c = getc(cfp);
while (c == '#')
{
fgets(line,256,cfp);
c = getc(cfp);
}
ungetc(c,cfp);
m=fscanf(cfp, "%d ", &nlayers);
if (m!=1)
{
printf("ERROR: Reading from configuration file.\n");
exit(1);
}
if (nlayers < 0)
{
printf("ERROR: Negative number of hidden layers.\n");
exit(1);
}
nlayers += 2;
/*
* descriptions of # of units per layer
*/
layer_descp = (int *)malloc(nlayers * sizeof(int));
c = getc(cfp);
while (c == '#')
{
fgets(line,256,cfp);
c = getc(cfp);
}
ungetc(c,cfp);
n = 0;
for (i=0; i<nsensors; i++) n += sensor_size(s_type[i]);
ldp = layer_descp;
*ldp = n;
x = n;
ldp++;
for (i=1; i < (nlayers-1); i++, ldp++)
{
m=fscanf(cfp, "%d ", ldp);
if (m!=1)
{
printf("ERROR: Reading from configuration file.\n");
exit(1);
}
if (*ldp <= 0)
{
printf("ERROR: Zero or negative number of hidden units.\n");
exit(1);
}
}
n = 0;
for (i=0; i<nmotors; i++) n += motor_size(m_type[i]);
if (learn == 2) *ldp = n+x;
else *ldp = n;
if ((*layer_descp > NINPUTS) || (*(layer_descp+nlayers-1) > NOUTPUTS))
{
printf("ERROR: number of input or output units too large.\n");
printf(" Use fewer sensors/motors, or increase neural net\n");
printf(" size limits (file defs.h) and recompile code.\n");
exit(1);
}
/*
* gut size
*/
c = getc(cfp);
while (c == '#')
{
fgets(line,256,cfp);
c = getc(cfp);
}
ungetc(c,cfp);
m=fscanf(cfp, "%d ", &gutsize);
if (m!=1)
{
printf("ERROR: Reading from configuration file.\n");
exit(1);
}
if (gutsize < 0)
{
printf("ERROR: Negative gutsize.\n");
exit(1);
}
/*
* get the reaction matrix entries
*/
c = getc(cfp);
while (c == '#')
{
fgets(line,256,cfp);
c = getc(cfp);
}
ungetc(c,cfp);
if (unary_reactions)
for (x=0; x<types; x++)
{
m=fscanf(cfp, "(%*d,%f", &react_table[x][0].energy);
if (m!=1)
{
printf("ERROR: Reading from configuration file.\n");
exit(1);
}
for (y=0; y<types; y++) fscanf(cfp, ",%*d");
fscanf(cfp, ") ");
}
else
for (x=0; x<types; x++)
for (y=0; y<types; y++)
{
m=fscanf(cfp, "(%d,%f", &react_table[x][y].possible, &react_table[x][y].energy);
if (m!=2)
{
printf("ERROR: Reading from configuration file.\n");
exit(1);
}
if ((react_table[x][y].possible!=0) && (react_table[x][y].possible!=1))
{
printf("ERROR: Incorrect reaction parameter(s).\n");
printf(" Please follow directions in configuration\n");
printf(" file and adjust parameters accordingly.\n");
exit(1);
}
for (z=0; z<types; z++)
{
m=fscanf(cfp, ",%d", &react_table[x][y].by_prod[z]);
if (m!=1)
{
printf("ERROR: Reading from configuration file.\n");
exit(1);
}
if (react_table[x][y].by_prod[z] < 0)
{
printf("ERROR: Negative number of by-products.\n");
printf(" Please follow directions in configuration\n");
printf(" file and adjust parameters accordingly.\n");
exit(1);
}
}
fscanf(cfp, ") ");
}
fclose(cfp);
}
usage()
{
printf("\nCOMMAND-LINE OPTIONS:\n\n");
printf("-R #\tuse # to seed random generator\n");
printf("-L #\tuse learning: 1 reinforcement, 2 prediction\n");
printf("-E #\trecord prediction error in .err file every # sweeps\n");
printf("-f #\tspecify <filename> for configuration file\n");
printf("-S \tno world replenishment if saturated\n");
printf("-s #\trun for # sweeps\n");
printf("-po \tprint informations each cycle\n");
printf("-r #\tuse learning rate #\n");
printf("-G #\tnumber of generations\n");
printf("-P #\tsize of initial population\n");
printf("-g #\tstart generation\n");
printf("-h #\tmutations range\n");
printf("-n #\tpercent of weights mutated (0-100)\n");
printf("-o #\tpercent of biases mutated (0-100)\n");
printf("-b \tdo not mutate biases\n");
printf("-U \tunary reactions\n");
printf("-v #\tverbose mode (0-4)\n");
printf("-d #\tsave only best # individuals of generation\n");
printf("-e #\tsave individuals each # generations\n");
printf("-u \tusage\n");
}